Stream API 教程
概述
Stream API 是 Java 8 引入的一个强大的工具,用于处理集合数据。它提供了一种声明式的方式来处理数据,使得代码更加简洁和易读。Stream API 可以与 Lambda 表达式结合使用,进一步提高代码的可读性和简洁性。
1. Stream API 的基本概念
1.1 什么是 Stream?
Stream 是一个来自数据源的元素队列,并支持聚合操作。数据源可以是集合、数组或其他数据结构。Stream 操作可以是中间操作(返回另一个 Stream)或终端操作(返回结果或副作用)。
1.2 Stream 的特点
- 声明式:Stream API 允许你以声明式的方式描述你想要做什么,而不是如何做。
- 惰性求值:许多 Stream 操作是惰性的,只有在终端操作被调用时才会执行。
- 并行处理:Stream 可以轻松地并行处理数据,提高处理速度。
2. Stream 的创建
2.1 从集合创建 Stream
你可以从 Collection 接口的实现类(如 List、Set)中创建 Stream:
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();
}
}
2.2 从数组创建 Stream
你可以使用 Arrays.stream() 方法从数组创建 Stream:
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
String[] array = {"a", "b", "c"};
Stream<String> stream = Arrays.stream(array);
}
}
2.3 使用 Stream.of() 创建 Stream
你可以使用 Stream.of() 方法创建一个包含指定元素的 Stream:
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
Stream<String> stream = Stream.of("a", "b", "c");
}
}
3. Stream 的中间操作
3.1 filter()
filter() 方法用于过滤 Stream 中的元素,返回一个包含符合条件的元素的 Stream:
import java.util.Arrays;
import java.util.List;
public class StreamExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.stream()
.filter(n -> n % 2 == 0)
.forEach(System.out::println); // 输出 2, 4
}
}
3.2 map()
map() 方法用于将 Stream 中的每个元素映射为另一个元素,返回一个包含映射后元素的 Stream:
import java.util.Arrays;
import java.util.List;
public class StreamExample {
public static void main(String[] args) {
List<String> words = Arrays.asList("hello", "world");
words.stream()
.map(String::toUpperCase)
.forEach(System.out::println); // 输出 HELLO, WORLD
}
}
3.3 sorted()
sorted() 方法用于对 Stream 中的元素进行排序,返回一个排序后的 Stream:
import java.util.Arrays;
import java.util.List;
public class StreamExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(5, 3, 1, 4, 2);
numbers.stream()
.sorted()
.forEach(System.out::println); // 输出 1, 2, 3, 4, 5
}
}
4. Stream 的终端操作
4.1 forEach()
forEach() 方法用于对 Stream 中的每个元素执行指定的操作:
import java.util.Arrays;
import java.util.List;
public class StreamExample {
public static void main(String[] args) {
List<String> words = Arrays.asList("hello", "world");
words.stream()
.forEach(System.out::println); // 输出 hello, world
}
}
4.2 collect()
collect() 方法用于将 Stream 中的元素收集到一个集合中:
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StreamExample {
public static void main(String[] args) {
List<String> words = Arrays.asList("hello", "world");
List<String> upperCaseWords = words.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println(upperCaseWords); // 输出 [HELLO, WORLD]
}
}
4.3 reduce()
reduce() 方法用于将 Stream 中的元素归约为一个值:
import java.util.Arrays;
import java.util.List;
public class StreamExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
.reduce(0, (a, b) -> a + b);
System.out.println(sum); // 输出 15
}
}
5. 实践练习
练习 1:过滤和映射
编写一个程序,从一个包含整数的列表中过滤出偶数,并将这些偶数平方后输出。
import java.util.Arrays;
import java.util.List;
public class StreamExercise {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
numbers.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * n)
.forEach(System.out::println); // 输出 4, 16, 36
}
}
练习 2:排序和收集
编写一个程序,从一个包含字符串的列表中按字符串长度排序,并将排序后的结果收集到一个新的列表中。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StreamExercise {
public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "banana", "cherry", "date");
List<String> sortedWords = words.stream()
.sorted((a, b) -> Integer.compare(a.length(), b.length()))
.collect(Collectors.toList());
System.out.println(sortedWords); // 输出 [date, apple, banana, cherry]
}
}
6. 总结
Stream API 是 Java 中处理集合数据的一个强大工具。通过 Stream API,你可以以声明式的方式处理数据,使得代码更加简洁和易读。Stream API 还支持惰性求值和并行处理,进一步提高了代码的效率。
通过本教程的学习,你应该已经掌握了 Stream API 的基本概念、创建方式、中间操作和终端操作,并能够编写简单的 Stream 处理程序。继续练习和探索,你将能够更加熟练地使用 Stream API 来处理各种数据处理任务。